#!/usr/bin/perl

# ---------- Init variables -------
#my $version = "0.0001";
# ---------- external readable parameters -------
## Functions
##-------------------------------------------------------
#
# stict syntax checking.
use strict;
use CGI qw(param);
use SNMP_util;
use SIM_base;
use SIM_settings;

#BEGIN { $Exporter::Verbose=1 }

# Startupscript translater
my $module = $ARGV[0];
my $tool = $ARGV[1];
my $action = $ARGV[2];
my $option1 = $ARGV[3];
my $option2 = $ARGV[4];
my $option3 = $ARGV[5];
my $option4 = $ARGV[6];


my $backHeader="black";
my $httpUser = $ENV{'REMOTE_USER'};
my $httpReF = $ENV{'HTTP_REFERER'};
my $httpScriptName = $ENV{'SCRIPT_NAME'};
my $httpUserIp = $ENV{'REMOTE_ADDR'};
my $httpServerName = $ENV{'HTTP_HOST'};
my $httpCookie = $ENV{'HTTP_COOKIE'};
my $httpHost = $ENV{'HTTP_HOST'};
my $switchInfoDir = $ENV{'SIM_SWITCHINFO'};
my $ipDatabaseDir = $ENV{'SIM_IPDATAB'};
my $deviceDir = "$ENV{'SIM_DEVICED'}" || die "Oops no env found for SIM_DEVICED.";
my $oidDir = "$ENV{'SIM_OIDHELPD'}" || die "Oops no env found for SIM_OIDHELPD.";
my $graphDir = "$ENV{'SIM_GRAPHTMPDIR'}" || die "Oops no env found for SIM_GRAPHTMPDIR.";
my $tmpDir = "$ENV{'SIM_TMPDIR'}" || die "Oops no env found for SIM_TMPDIR.";
my $manDomain = "$ENV{'SIM_MANDOMAIN'}" || die "Oops no env found for SIM_MANDOMAIN.";
my $devConfigDir = "$ENV{'SIM_CONFIGD'}" || die "Oops no env found for SIM_CONFIGD.";


sub catFile {
  my $output = "";
  my ($file) = @_;
  open FH, $file or $output = "none";
# $output = readline FH;
  $output = <FH>;
  close FH;
  return $output;
}

sub catFileLine {
  my $outPut = "";
  my ($file) = @_;
  open FH, $file or $outPut = "$file";
  $outPut = <FH>;
  close FH;
  chomp($outPut);  # remove the newline
  return $outPut;
}

sub printFileLine {
  my $file = "@_[0]";
  my $varName = "@_[1]";
  my $rest = "@_[2]";
  my $logFile = "@_[3]";
  my $oldVal = catFileLine ("$file");
# print ("Update file=$file, varName=$varName, content:$rest<BR>");
  if ( "$oldVal" ne "$rest" ) {
    open(OUT, ">$file") || die "cannot create $file: $! (file=$file, varName=$varName, rest=$rest)";
    if ( "$logFile" ne "quiet" ) {
      print ("$varName is gewijzigd, oud:$oldVal nieuw:$rest<BR>");
    }
    print OUT $rest;
    close(OUT);
  }
}

sub testParam {
  my $file = "@_[0]";
  my $parameter = "@_[1]";
  my $update = "@_[2]";
  my $result = param("$parameter");
  if ( "$result" eq "" ) {
#   print("cat ");
    $result = &catFileLine("$file");
  } else {
    if ( "$update" eq "upd" ) { 
      printFileLine("$file","$parameter","$result","nquiet");
    }
  }
# print("$result $file<BR>");
  return("$result");
}

sub testNameStrict {
  my $testname = "@_[0]";
  my $type = "@_[1]";
  if ( "$type" eq "word" ) {
    $testname =~ tr#a-zA-Z[\xE0][\xE8][\xEC][\xF2][\xF9]##cd;
  } else {
    $testname =~ tr#a-zA-Z0-9[\@][\.][\-]#A#cds;
  }
  #print ("testname=$testname");
  return $testname;
}

sub testMkDir {
  my $dirName = "@_[0]";
  if ( !-d $dirName ) {
    system "mkdir -p $dirName";
  }
}

sub printHead {
  my $dispHead = "@_[0]";
  print("
        <TABLE WIDTH=100% BORDER=0 CELLSPACING=0><TR BGCOLOR=#EEEEEE><TD COLSPAN=3><CENTER>
        Options:
        <A HREF=$httpScriptName?$module+$tool+intDown>interfaces down</A> |
        <A HREF=$httpScriptName?$module+$tool+ciscoDevInfo>Cisco device info</A> |
        <A HREF=$httpScriptName?$module+$tool+deviceConfigs>Configs</A>
	</TD></TR>
	</TABLE>
        ");
}

sub readUpdParam {
  my $workDir = "@_[0]";
  my $name = "@_[1]";
  my $type = "@_[2]";
  my $param = param("$name");
  if ( "$type" eq "fill" ) {
    $param=~s/ /_/g;
  }
  if ( "$param" eq "" ) {
    $param = catFileLine("$workDir");
  } else {
    printFileLine("$workDir","$name","$param");
  }
  return $param;
}
sub getIpDir {
  my $workDir = "@_[0]";
  $workDir =~ s#\.#/#g;
  $workDir = "$ipDatabaseDir/$workDir";
  return $workDir;
}


sub ciscoDevInfo {
  my $vendor = "$_[0]";
  my $searchList = "$_[1]";
  $searchList = lc($searchList);
  my $workDir = "$deviceDir/$vendor";
  chdir($workDir);
  my @deviceList;
  if ( "$searchList" eq "none" ) {
     $searchList = param('fileString');
  }
  if ( $vendor eq "none" ) {
    print("<CENTER>");
    if ( -d $SIMparam{'SIMdeviceDir'} ) {
      print("<H2>Select a vendor:</H2>");
      chdir $SIMparam{'SIMdeviceDir'};
      my @devices = <*>;
      foreach my $entry (@devices) {
        print(". <A HREF=$httpScriptName?$module+$tool+ciscoDevInfo+$entry>$entry</A> .");
      }
    } else {
      print("devicedir SIMdeviceDir not found.");
    }
  } else {
    if ( "$searchList" eq "" ) {
       @deviceList = <*>;
       $searchList = "all";
    } else {
       @deviceList = <$searchList*>;
    }
    print("
       <FORM   method=post Action=$httpScriptName?$module+$tool+ciscoDevInfo>
        <CENTER>
         Device search string: <INPUT NAME=fileString Size=30 Type=text> <INPUT TYPE=submit Value=Report> </FORM>
          </FORM>
          ");

    print("<H2>$vendor device info for $searchList.</H2>");
    print("<TABLE>");
    my $outFile = "CiscoDeviceInventory-$manDomain-$searchList.csv";
    my $moduleFile = "CiscoModuleInventory-$manDomain-$searchList.csv";
    open( DEV, ">$graphDir/$outFile" ) || die "Oops, could not open $outFile to save info.";
    open( MOD, ">$graphDir/$moduleFile" ) || die "Oops, could not open the module file to save info.";
    print DEV ("\"ReccordType\",\"DeviceName\",\"CW_FAMILY\",\"CW_IMAGE\",\"CW_VERSION \",\"CW_FEATURE\",\"CW_MODULE\",\"CW_SYSDESCR\"\n");
    print MOD ("\"ReccordType\",\"DeviceName\",\"Position/Slot\",\"ModName\",\"ModDescr\",\"FwLevel\",\"SwLevel\",\"Serail\",\"Manufacturer\"\n");
    foreach my $devName (@deviceList) {
      my $workDir = "$workDir/$devName";
      my $ipAddr = catFileLine("$workDir/ipaddr");
      my $ipDir = getIpDir($ipAddr);
      my $oidInfo = catFileLine("$ipDir/snmpoid.txt");
      my ($deviceType, $rest) = split(' ', $oidInfo);
      print("<TR BGCOLOR=#FFFF00><TD><FONT SIZE=+1><B>Info for <A HREF=$httpScriptName?mon+nodestatus+$ipAddr>$devName</A></B></FONT></TD>
               <TD COLSPAN=9>($deviceType)</TD></TR>");
      my @CWList = qw( CW_FAMILY CW_IMAGE CW_VERSION CW_FEATURE CW_MODULE CW_SYSDESCR );
      print DEV ("\"device\",\"$devName\""); 
      foreach my $entry (@CWList) {
        my $var;
        if ( -f "$workDir/$entry" ) {
          $var = catFileLine("$workDir/$entry");
          print("<TR><TD BGCOLOR=#FFFF88>$entry:</TD><TD BGCOLOR=#FFFF44 COLSPAN=6>$var.</TD></TR>");
        }
        print DEV (",\"$var\"");
      }
      print DEV ("\n");
      print("</TR>");
      if ( -f "$workDir/moduleList" ) {
        print("<TR BGCOLOR=#DDDDDD>
                 <TD>Position / Slot</TD>
                 <TD>Mod Name</TD>
                 <TD>Mod Descr</TD>
                 <TD>Firmware</TD>
                 <TD>Sw level</TD>
                 <TD>Serial</TD>
                 <TD>Manufacturer</TD>
               </TR>");
        my $modList = catFileLine("$workDir/moduleList");
        my @serialList = split(' ', $modList);
        foreach my $serial (@serialList) {
          my $Position = catFileLine("$workDir/module-$serial-Position");
          my $ModelName = catFileLine("$workDir/module-$serial-ModelName");
          my $Descr = catFileLine("$workDir/module-$serial-Descr");
          my $FirmwareRev= catFileLine("$workDir/module-$serial-FirmwareRev");
          my $SoftwareRev = catFileLine("$workDir/module-$serial-SoftwareRev");
          my $MfgName = catFileLine("$workDir/module-$serial-MfgName");
          print("<TR VALIGN=top>
                   <TD>$Position</TD>
                   <TD>$ModelName</TD>
                   <TD>$Descr</TD>
                   <TD>$FirmwareRev</TD>
                   <TD>$SoftwareRev</TD>
                   <TD>$serial</TD>
                   <TD>$MfgName</TD>
                 </TR>");
          print MOD ("\"module\",\"$devName\",\"$Position\",\"$ModelName\",\"$Descr\",\"$FirmwareRev\",\"$SoftwareRev\",\"$serial\",\"$MfgName\",\n");
        }
      }
    }
    close DEV;
    close MOD;
    print("<TR><TD COLSPAN=10 BGCOLOR=#AAAAAA>
      <CENTER>Csv files:
      <A HREF=/graphs/$outFile>$outFile</A> | 
      <A HREF=/graphs/$moduleFile>$moduleFile</A></TD></TR>");
    print("</TABLE>");
  }
}

sub displayInterfaces {
  my $fileString = "@_[0]";
  my $numDays = "@_[1]";
  my $workDir = "$switchInfoDir/devices";
  if ( "$fileString" eq "none" ) {
    $fileString = param("fileString");
    $fileString = lc $fileString;
  } else {
    $fileString = "";
  }
  if ( "$numDays" eq "" ) {
    $numDays = param("numDays");
  }
  if ( "$numDays" eq "" ) {
    print("
     <FORM   method=post Action=$httpScriptName?$module+$tool+intDown>
      <CENTER><TABLE>
       <TR><TD>Devicenames starting with:</TD><TD><INPUT NAME=fileString Size=30 Type=text></TD></TR>
       <TR><TD>Days down:</TD><TD><INPUT NAME=numDays Size=30 Type=text  VALUE=30></TD></TR>
       <TR><TD COLSPAN=2><CENTER><INPUT TYPE=submit Value=Search></TD></TR>
      </TABLE>
	</FORM>
          ");
  } elsif ( !-d $workDir ) {
    print ("OOps, directory ($workDir) not found....");
  } else {
    chdir "$workDir";
    my @list = <$fileString*>;
    print("<CENTER><TABLE>");
    foreach my $entry (@list) {
      my $ipInfo = catFileLine("$entry/switchip");
      my ( $ipAddr, $snmpComm ) = split(' ', $ipInfo);
      #my $ipDir = "$ipDatabaseDir/$ipAddr";
      #$ipDir =~ s#\.#\/#g;
      #my $snmpComm = catFileLine("$ipDir/snmpcomm.txt");
      my $HOST = $snmpComm . "@" . $ipAddr;
      my $response = &snmpget($HOST, "1.3.6.1.2.1.1.5.0");
      $response = lc $response;
      my ( $shortHostname, $restHostName ) = split( '\.', $response, 2 );
      if ( "$shortHostname" ne "$entry" ) {
        print("<TR BGCOLOR=#88FFFF><TD COLSPAN=4>$entry has a problem, not included in the report ($shortHostname, $entry)</TD></TR>");
      } else {
        my $uptime = &snmpget($HOST, "1.3.6.1.2.1.1.3.0");
        print("
          <TR BGCOLOR=#DDDDDD><TD COLSPAN=4>$shortHostname.$restHostName (uptime: $uptime)</TD></TR>
          <TR><TD>Device</TD><TD>Interface</TD><TD>Description</TD><TD>Days down</TD></TR>
              ");
        
        #interface-info
        open (INTLIST, "$entry/interface-info");
        while (my $regel = <INTLIST>) {
          my ( $intNum, $intName, $description ) = split(' ', "$regel", 3);
          #.1.3.6.1.2.1.2.2.1.8.intnum = switchOper
          #.1.3.6.1.2.1.2.2.1.7.intnum = switchAdmin
          my $intStatus = &snmpget($HOST, "1.3.6.1.2.1.2.2.1.8.$intNum");
          if ( "$intStatus" eq "2" ) {
            my $adminStatus = &snmpget($HOST, "1.3.6.1.2.1.2.2.1.7.$intNum");
            if ( "$adminStatus" eq "1" ) {
              my $intChanged = &snmpget($HOST, "1.3.6.1.2.1.2.2.1.9.$intNum");
              my $calcChanged = $uptime - $intChanged;
              if ( $calcChanged >= $numDays ) {
                print("<TR BGCOLOR=#FFBBFF><TD>$entry</TD>
                                         <TD>$intName</TD>
                                         <TD>$description</TD>
                                         <TD ALIGN=center>$calcChanged</TD></TR>");

              }
            }
          }
        }
        close(INTLIST);
      }
    }
    print("</TABLE>");
  }
}

sub deviceConfigs {
  my $deviceType = "@_[0]";
  my $currDir = "$devConfigDir/current";
  my $infoDir = "$devConfigDir/info";
  my $now = time;
  my $last = $now - 172800;
  my $currDate = printDate( $now, "yyyymmdd" );
  if (( "$deviceType" eq "" ) or ( ! -d "$deviceDir/$deviceType" )) {
    chdir $deviceDir;
    my @deviceTypes = <*>;
    print("<CENTER>");
    foreach my $entry (@deviceTypes) {
      print(".<A HREF=$httpScriptName?$module+$tool+deviceConfigs+$entry>$entry</A> .");
    }
  } else {
    chdir "$deviceDir/$deviceType";
    my @configList = <*>;
    print("<TABLE>
             <TR>
               <TD>Device ip</TD>
               <TD>File / device</TD>
               <TD>Last changed</TD>
               <TD>Last checked</TD>
             </TR>");
    foreach my $entry (@configList) {
      my ( $currTime, $checkedTime );
      if ( -f "$currDir/$entry" ) {
        my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("$currDir/$entry");
        $currTime = $ctime;
      }
      if ( -f "$infoDir/tested-$entry" ) {
        my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("$infoDir/tested-$entry");
        $checkedTime = $ctime;
      } else {
        $checkedTime = "";
      }
      if ( "$checkedTime" < "$last" ) {
        my $ipaddr = catFileLine("$deviceDir/$deviceType/$entry/ipaddr");
	my $ipDir = getIpDir($ipaddr);
	my $recType = catFileLine("$ipDir/sipmanrectype.txt");
	if (( "$recType" ne "ext" ) and ( "$recType" ne "standby" )) {
          my $dispCurrTime = printDate( $currTime, "yyyymmdd" );
          my $dispCheckedTime = printDate( $checkedTime, "yyyymmdd" );
          my $snmpName = catFileLine("$ipDir/hostname.txt");
          my $logFile = "$SIMparam{'SIMdevConfigLogs'}/copyRun-$snmpName";
          my $url = "none";
          if ( -f $logFile ) {
            $url = "<A HREF=$httpScriptName?file2+typeDevConfigsLogs+copyRun-$snmpName>logfile</A>";
          }
          print("<TR>
                   <TD>$ipaddr</TD>
                   <TD><A HREF=$httpScriptName?mon+nodestatus+$ipaddr>$entry</A></TD>
                   <TD>$dispCurrTime</TD>
                   <TD>$dispCheckedTime</TD>
                   <TD ALIGN=center>$url</TD>
                 </TR>");
	}
      }
    }
    print("</TABLE>");
  }
}

#--------------------------- Main ---------------------------
printHead;

if ( "$option1" eq "" ) {
  $option1 = "none";
}

if ( "$action" eq "deviceConfigs" ) {
  deviceConfigs( $option1 );
} elsif ( "$action" eq "ciscoDevInfo" ) {
  ciscoDevInfo( $option1, $option2 );
} elsif ( "$action" eq "intDown" ) {
  displayInterfaces( $option1, $option2, $option3, $option4);
} elsif ( "$action" eq "search" ) {
  searchFiles ( $option1, $option2, $option3);
} else {
  print("<CENTER>Sellect an option from the above menu.");
}
